home *** CD-ROM | disk | FTP | other *** search
- /* Indent_Interface.c : Indent dialog interface */
- /* Copyright © 1986, 1988, 1989 1991 the Free Software Foundation, Inc.
- * This file is part of GAWK, the GNU implementation of the
- * AWK Progamming Language, modified for the Macintosh (also called Indent).
- * GAWK is free software; you can redistribute or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or any later version.
- * GAWK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with GAWK; see the file "COPYING Indent". If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * Written for THINK C 4 on the Macintosh by Ken Earle (Dynabyte) Aug 1991.
- */
-
- /* Code to synthesize a command line based on user's choices in the
- main Indent dialog, or pass a supplied command line after some
- substitution.
-
- Profile options: choose from a list of all Indent profiles in the
- folder "Indent profiles", or some other profile via a standard SFGetFile dialog.
-
- Indent input options:
- - Specific input file; the one "fixed" option, allows user to pick one particular
- input file as input
- - Selected front text / All of front text; takes as input all or the selected part
- of the text window that happens to be in front when Indent is called
- - MFS selected files; takes as input all files selected for multi-file operation
- in the calling application - usually multi-file searching.
-
- Indent output options:
- "\pBack up and overwrite": if MFS or one specific file
- "\pRename with number" : one specific file only
- "\pTo $tempStdOut" : if one specific file or stdin
-
- An "About" button displays copysquawk about Indent.
-
- Calling program may pass in a command line - if present, skip the
- Indent dialog, make argv's and go straight to AWKmain().
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- //#include <fcntl.h>
- #include <string.h>
- #include <setjmp.h>
- #include "CodeResHelper.h" /* TMalloc etc */
- #include "CodeResource.h"
- #include "AppCodeComm.h"
-
- // Some key constants
- #define ETX '\003' /* enter */
- #define BS '\b' /* backspace */
- #define HT '\t' /* tab */
- #define CR 0x0D /* return */
- #define ESC '\033' /* clear */
- #define FS '\034' /* left arrow */
- #define GS '\035' /* right arrow */
- #define RS '\036' /* up arrow */
- #define US '\037' /* down arrow */
- #define COMMA ',' /* or 0x2C */
- #define BLANK ' ' /* a space */
- #define OPTBL ' ' /* option-space */
-
- // And some macros for character handling
- #define alpha(c) (('a'<=(c)&&(c)<='z')||('A'<=(c)&&(c)<='Z')||(c)=='_')
- #define num(c) ('0'<=(c) && (c)<='9')
- #define alphanum(c) (alpha(c)||num(c))
- #define white(c) ((c) == BLANK || ((c) > 0 && (c) <= CR) || (c) == OPTBL)
-
-
- // Use better memory routines for allocating argv[]
- #define malloc(x) Fmalloc(x)
- #define realloc(x, y) Frealloc(x, y)
- #define free(x) Ffree(x)
-
- extern void *alloca(unsigned short size);
- extern void DumpZoneList(void);
-
- /* buffer holding position of long jump */
- jmp_buf envBuf;
-
- static short argc;
- static char **argv;
- static short NUMARGVS = 500; /* Was a #define, now variable */
-
- short gInputError; /* Not used yet */
-
- /* Struct recording user choices */
- typedef struct IndentSetup
- {
- short profileMenuNum; // profile item gnu, k&r, orig, other
- short inputType; // input file or "metafile" specification
- short outputType; // replace, keep backup, to stdout etc
- Boolean showOut; // passed back to calling application
- char *profileName; // the Indent profile
- char *inputName; // optional, if one specific file selected
- char *outputName; // optional, if -o option set
- short profileVRefNum; // for currently selected profile
- short defaultVRefNum; // for the folder "Indent programs"
- short otherVRefNum; // for "unlisted" profile
- } IndentSetup;
- /* global record of user choices */
- IndentSetup gIndentSetup;
-
- // For command line passed by user in text form.
- typedef enum CommandLineTypesEnum
- {
- kErrorGetting_Arg = -1,
- kNoMore_Arg = 0,
- kIndentName_Arg = 1,
- kStandardProfileNameArg = 2,
- kProfileName_Arg = 3,
- kFileName_Arg = 4,
- kMFS_Arg = 5,
- kStandardOutputArg = 6,
- kOutputFileNameFollowsArg = 7
- } CommandLineTypesEnum;
-
- /* Dialog to set up a Indent run.
- */
- #define IndentDlogID 410
- /* OK is 1, Cancel is 2 */
- #define AboutIndent 3
- #define ProgramStat 5
- #define InputStat 6
- #define OutputStat 7
- #define ProfilePopup 8
- #define InputPopup 9
- #define OutputPopup 10
- #define RunUserItem 11
-
- /* popups */
- #define MainProfileID 187
- #define InputID 188
- #define OutputID 189
-
- /* The "Take input from:" popup varies accoring to which extensions
- are supplied by the application: GetFrontText_Ext is nonnull only if
- it is appropriate to take input from a front text window - note this
- will be null even if the application supports the extension, in the case
- where no text file is open at the time this code resource is called.
- GetNextFileToSearch_Ext is nonnull if the application supports selecting
- multiple files somehow, the most common use being for multi-file
- searching. Again this will be passed in as NULL if there are no files
- selected at the time of the call.
- */
- typedef struct InputPopupItems
- {
- short frontSelected, // user's selected text in front text window
- frontAll, // all of text in front window
- multiSelected, // multiple files, as specified within application
- specificFile; // pick one with SFGetFIle
- } InputPopupItems, *InPopItemPtr;
- static InputPopupItems inPop;
-
- typedef struct OutputPopupItems
- {
- short replaceWithBackup,
- renameWithNumber,
- toStandardOut;
- } OutputPopupItems, *OutPopItemPtr;
- static OutputPopupItems outPop;
-
- /* from indent.c */
- extern void Indent_main(short argc, char **argv);
-
- /* Functions defined in this file: */
- short InvokeIndent(void); /* the external call - see Code_Main.c */
- void DoExiting(void);
- static pascal void EmptyExitToShell(void);
- void CleanUpAfterIndent(void);
- /* "command line" creation: */
- Boolean GetCommandLineArguments(void);
- Ptr FullPathNameForProfile
- (Ptr argPtr,
- short argLength,
- short *vRefNumP
- );
- short GetWorkingDirectory
- (char *curvolName,
- long theDirID
- );
- void InitIndentFromProfile(Ptr profileNamePtr);
- short GetNextCommandLineArg
- (Ptr *argPtrP,
- short *argLengthP
- );
- /* Dialog management */
- Boolean DoIndentDialog(void);
- void CreateIndentProgramResourcePopups(void);
- void MaintainOutputPopup(void);
- void CreateProfilePopup(void);
- long FindIndentProfileFolder(char *curvolName, char *folderName);
- void AddProfilesToMenu(char *curvolName, long theDirID, MenuHandle theMenu);
- void AlphaAppendMenu(MenuHandle theMenu, short lowPoint, char *name);
- short AlphaMenuPos(char *name, MenuHandle theMenu, short highPoint, short lowPoint);
- short MenuCompare(char *name, MenuHandle theMenu, short index);
- short PtrLenPascalCompare(Ptr spatPtr, short patLen, Ptr stargetPtr);
- pascal void IndentPopProc(WindowPtr wdPtr, short item);
- pascal void ButtonProc(WindowPtr wdPtr, short item);
- void ResetIndentSetup(DialogPtr dPtr);
- void SetPopupMark(short theMenuID, short newItem);
- void GetIndentProfileName(DialogPtr dPtr, short item);
- void GetInputFileName(void);
- void DestroyIndentPopups(void);
- Boolean GetCommandLineFromDlogResult(void);
- char *CreateStdIn(Boolean wholeFile);
- Boolean GetInputsFromMFS(void);
- char *GetRenumberedName(char *oldName);
- Boolean IncrementName(StringPtr copyOfName);
- void RedrawItem(DialogPtr dPtr, short itemHit);
- void RedrawDialog(DialogPtr dPtr);
- void JumpOnIndentError(short inputErrorNumber);
- void HandleIndentError(void);
-
- /* Memory init, get command line either as passed directly or from dialog,
- set watch cursor, call Indent_main, clean up, return result code.
- */
- short InvokeIndent(void)
- {
-
- InitTempCodeMemory(); /* see CodeResource_Helper.c */
-
- // Rev May 96, see if caller passed along a command line. If there is any failure
- // or just no command line, do the dialog.
- if (!GetCommandLineArguments())
- {
- //OKStopAlert("DBG could not get cmd line arguments");
- if (argv != NULL)
- {
- while (--argc >= 0)
- {
- if (argv[argc] != NULL)
- free(argv[argc]);
- }
- free(argv);
- }
- argv = NULL;
- argc = 0;
- if (!DoIndentDialog())
- {
- DoExiting();
- return(-1); /* user cancelled, most likely, or out of memory */
- }
- }
- SetWatchCursor();
-
- /* If Indent fails, it long-jumps back to here
- and setjmp returns non-zero. */
-
- if (!setjmp(envBuf))
- {
- //OKStopAlert("DBG about to call Indent_main");
- Indent_main(argc, argv);
- CleanUpAfterIndent();
- //_exiting(1);
- /* show result if wanted */
- DoExiting();
- if (gIndentSetup.showOut)
- {
- return(1);
- }
- return(0);
- }
- else
- {
- CleanUpAfterIndent();
- //_exiting(1);
- HandleIndentError();
- DoExiting();
- if (gInputError)
- return(-2);
- else
- return(1);
- }
- }
-
- enum
- {
- uppExitToShellProcInfo = kPascalStackBased
- };
- // Patch ExitToShell out temporarily and call exit()
- void DoExiting(void)
- {
- pascal void (*gOldExitToShell)(void);
- UniversalProcPtr EmptyExitToShellProcPtr;
-
- gOldExitToShell = (void *)GetToolTrapAddress(0xA9F4);
- EmptyExitToShellProcPtr = NewRoutineDescriptor((ProcPtr)&EmptyExitToShell,
- uppExitToShellProcInfo,
- GetCurrentISA());
- SetToolTrapAddress(EmptyExitToShellProcPtr, 0xA9F4);
- exit(0);
- SetToolTrapAddress((UniversalProcPtr)gOldExitToShell, 0xA9F4);
- }
-
- static pascal void EmptyExitToShell(void)
- {
- ;
- }
-
- void CleanUpAfterIndent(void)
- {
- /* Call TFreeAll if using TMalloc etc, call FFreeAll if using Fmalloc etc
- -at present, using Fmalloc which is better on all scores. */
-
- FFreeAll();
- //alloca(0); not needed
- }
-
- /*
- Under version 4, caller may pass along a command line in text form. If so,
- parse it into argv. Return TRUE if got a good command line, FALSE otherwise.
- Memory allocation is done here, advancing through the text of the command line is
- done by GetNextCommandLineArg().
- For program names, use Indent program folder if no path specified.
- For input, "MFS" means multi-file selection (if allowed), case-sensitive there.
- */
- Boolean GetCommandLineArguments(void)
- {
- Ptr argPtr = NULL;
- short argLength = 0;
- Ptr tempPtr;
- Ptr profileNamePtr = NULL;
- long len;
- short i;
- short argumentType;
- short vRefNum = 0;
- short programArgument = 0;
- Boolean gotCommandLine = FALSE;
-
- // init IndentSetup.
- gIndentSetup.showOut = FALSE;
- gIndentSetup.profileName = gIndentSetup.inputName = NULL;
- gIndentSetup.outputName = NULL;
-
- argc = 0;
-
- if ( gacc.extend2ID == 'VER4'
- && gacc.commandLine != NULL )
- {
- gotCommandLine = TRUE;
- argv = (char **)malloc( sizeof(char *) * NUMARGVS );
- if (argv == NULL)
- {
- OKStopAlert("Could not allocate argv array, ouch!");
- return(FALSE);
- }
- while ( (argumentType = GetNextCommandLineArg(&argPtr, &argLength)) > 0)
- {
- switch (argumentType)
- {
- case kIndentName_Arg:
- //OKStopAlert("DBG about to allocate code name");
- // hawk name always as first arg
- len = strlen(gacc.thisCodeName);
- argv[argc] = (Ptr)malloc(len+1);
- if (!argv[argc])
- {
- OKStopAlert("Could not allocate Indent name, ouch!");
- return(FALSE);
- }
- BlockMove(gacc.thisCodeName, argv[argc], len+1);
- ++argc;
- break;
- case kProfileName_Arg:
- //OKStopAlert("DBG about to allocate program name");
- profileNamePtr = FullPathNameForProfile(argPtr, argLength, &vRefNum);
- if (profileNamePtr == NULL)
- {
- OKStopAlert("Could not allocate profile name, ouch!");
- return FALSE;
- }
- break;
- case kOutputFileNameFollowsArg:
- //OKStopAlert("DBG about to allocate dash oh");
- tempPtr = (Ptr)malloc(3);
- if (tempPtr == NULL)
- {
- OKStopAlert("Could not allocate -o separator, ouch!");
- return FALSE;
- }
- BlockMove("-o", tempPtr, 3);
- argv[argc] = tempPtr;
- ++argc;
- break;
- case kStandardOutputArg:
- //OKStopAlert("DBG about to allocate dash st");
- tempPtr = (Ptr)malloc(4);
- if (tempPtr == NULL)
- {
- OKStopAlert("Could not allocate -st, ouch!");
- return FALSE;
- }
- BlockMove("-st", tempPtr, 4);
- argv[argc] = tempPtr;
- ++argc;
- break;
- case kFileName_Arg:
- case kStandardProfileNameArg:
- //OKStopAlert("DBG about to allocate one input or output file");
- tempPtr = (Ptr)malloc(argLength + 1);
- if (tempPtr == NULL)
- {
- OKStopAlert("Could not allocate input file name, ouch!");
- return FALSE;
- }
- BlockMove(argPtr, tempPtr, argLength);
- tempPtr[argLength] = '\0';
- argv[argc] = tempPtr;
- ++argc;
- break;
- case kMFS_Arg:
- //OKStopAlert("DBG about to allocate all MFS files");
- if (!GetInputsFromMFS())
- {
- OKStopAlert("Could not get MFS file names, ouch!");
- return FALSE;
- }
- break;
- default:
- // unknown argument type
- break;
- } // switch
- } // while
-
- if (argc < 2)
- {
- OKStopAlert("\"Indent\" was followed by insufficient information to run!");
- return FALSE;
- }
- else
- {
- // Load profile if one was mentioned
- if (profileNamePtr != NULL)
- {
- InitIndentFromProfile(profileNamePtr);
- }
- }
-
- // Tack on "-npro" to suppress reading default profile
- tempPtr = (Ptr)malloc(6);
- if (tempPtr == NULL)
- {
- OKStopAlert("Could not allocate -npro, ouch!");
- return FALSE;
- }
- BlockMove("-npro", tempPtr, 6);
- argv[argc] = tempPtr;
- ++argc;
- } // if v4 with cmd line
-
- return gotCommandLine;
- }
-
- /* If we don't already have a full path, use the Indent profile folder
- to make one. */
- Ptr FullPathNameForProfile
- (Ptr argPtr,
- short argLength,
- short *vRefNumP
- )
- {
- char curvolName[32];
- char pProgName[64];
- long theDirID = 0;
- short vRefNum = *vRefNumP;
- Ptr tempPtr = NULL;
- long len;
- Ptr cPtr;
- Ptr endPtr;
-
- // Does the program name contain a colon?
- cPtr = argPtr;
- endPtr = cPtr + argLength;
- for (; cPtr < endPtr; ++cPtr)
- {
- if (*cPtr == ':')
- break;
- }
- // No colon means we have to make the full path name
- if (cPtr >= endPtr)
- {
- if (argLength > 63)
- argLength = 63;
- BlockMove(argPtr, pProgName + 1, argLength);
- pProgName[0] = argLength;
- if ( vRefNum != 0
- || (theDirID = FindIndentProfileFolder(curvolName, (char *)"\pIndent profiles")) != 0 )
- {
- if (theDirID != 0)
- {
- vRefNum = GetWorkingDirectory(curvolName, theDirID);
- *vRefNumP = vRefNum;
- }
- tempPtr = (Ptr)malloc(256);
- if (tempPtr != NULL)
- {
- AppendPStr((Byte *)(FullPathNameFromVRefNum(vRefNum,(Byte *)(tempPtr))),
- (Byte *)(pProgName));
- PtoCstr((StringPtr)tempPtr);
- }
- }
- }
- // If it has a colon, just tack '-f' in front of a copy.
- else
- {
- tempPtr = (Ptr)malloc(argLength + 1);
- if (tempPtr != NULL)
- {
- BlockMove(argPtr, tempPtr, argLength);
- tempPtr[argLength] = '\0';
- }
- }
- return tempPtr;
- }
-
- short GetWorkingDirectory
- (char *curvolName,
- long theDirID
- )
- {
- WDPBRec theParms;
- HVolumeParam vParms;
- char volName[32];
- short theVolRef, vRefNum;
-
- /* Some shenanigans to open working directory for code resources */
- BlockMove(curvolName, volName, 32);
- vParms.ioCompletion = NULL;
- vParms.ioNamePtr = (StringPtr)(volName);
- vParms.ioVRefNum = -32768;
- vParms.ioVolIndex = -1;
- if (PBHGetVInfo((HParmBlkPtr)&vParms, FALSE))
- theVolRef = 0;
- else
- theVolRef = vParms.ioVRefNum;
- theParms.ioCompletion = NULL;
- theParms.ioVRefNum = theVolRef;
- theParms.ioNamePtr = NULL;
- theParms.ioWDDirID = theDirID;
- theParms.ioWDProcID = 'ERIK';
- if (PBOpenWD(&theParms, FALSE)) /* IM IV pg 158 */
- vRefNum = 0;
- else
- vRefNum = theParms.ioVRefNum;
-
- theParms.ioNamePtr = NULL;
- theParms.ioVRefNum = vRefNum;
- theParms.ioWDIndex = 0;
- theParms.ioWDProcID = 0;
- if (PBGetWDInfo(&theParms,false))
- vRefNum = 0;
- return vRefNum;
- }
-
- /* Grab contents of file profileNamePtr, load them into indent variables.
- */
- void InitIndentFromProfile(Ptr profileNamePtr)
- {
- extern void initialize_backups(void);
- extern void set_defaults(void);
- extern char *set_profile (char *customFileName);
-
- initialize_backups();
- set_defaults();
- set_profile(profileNamePtr);
- }
-
- /* Grab the next command line argument, determine its type, or return 0.
- Being nice, we strip out quotes here.
- Pass *argPtrP = NULL the first time.
- kErrorGetting_Arg = -1,
- kNoMore_Arg = 0,
- kIndentName_Arg = 1,
- kStandardProfileNameArg = 2,
- kProfileName_Arg = 3,
- kFileName_Arg = 4,
- kMFS_Arg = 5,
- kStandardOutputArg = 6,
- kOutputFileNameFollowsArg = 7
- */
- short GetNextCommandLineArg
- (Ptr *argPtrP,
- short *argLengthP
- )
- {
- Ptr argPtr = *argPtrP;
- Ptr endPtr;
- short argLength = *argLengthP;
- short argumentType = kNoMore_Arg;
- long commandLineLength; // needed when stripping quotes
- long amountToMove; // ditto
- Boolean stripQuotes = FALSE;
-
- if (argPtr == NULL)
- {
- argPtr = gacc.commandLine;
- argumentType = kIndentName_Arg;
- }
- else
- argPtr += argLength;
- argLength = 0;
-
- // skip past last arg's quote
- while (*argPtr == '"')
- ++argPtr;
- // skip white space
- while (white(*argPtr))
- ++argPtr;
- // First arg is "Indent"
- if (argumentType == kIndentName_Arg)
- {
- endPtr = argPtr;
- while (*endPtr && !white(*endPtr))
- ++endPtr;
- }
- // Options indicate source program, variable, input follows
- else if (*argPtr == '-')
- {
- ++argPtr;
- endPtr = argPtr;
- while (*endPtr && !white(*endPtr))
- ++endPtr;
- // -, -o, -st, -MFS, -gnu, -kr, -orig
- if (endPtr == argPtr)
- argumentType = kErrorGetting_Arg;
- else if (endPtr - argPtr == 1)
- {
- if (*argPtr == 'o')
- argumentType = kOutputFileNameFollowsArg;
- }
- else if (endPtr - argPtr == 2)
- {
- if (*argPtr == 's' && *(argPtr+1) == 't')
- argumentType = kStandardOutputArg;
- else if (*argPtr == 'k' && *(argPtr+1) == 'r')
- argumentType = kStandardProfileNameArg;
- }
- else if (endPtr - argPtr == 3)
- {
- if ( *argPtr == 'M' && *(argPtr+1) == 'F'
- && *(argPtr+2) == 'S' )
- argumentType = kMFS_Arg;
- else if ( *argPtr == 'g' && *(argPtr+1) == 'n'
- && *(argPtr+2) == 'u' )
- argumentType = kStandardProfileNameArg;
- }
- else if (endPtr - argPtr == 4)
- {
- if ( *argPtr == 'o' && *(argPtr+1) == 'r'
- && *(argPtr+2) == 'i' && *(argPtr+3) == 'g' )
- argumentType = kStandardProfileNameArg;
- }
- else
- {
- argumentType = kErrorGetting_Arg;
- }
- }
- // No option, must be input file or profile file
- else if (*argPtr)
- {
- argumentType = kFileName_Arg;
- endPtr = argPtr;
- // file name, optionally in quotes
- if (*argPtr == '"')
- {
- ++argPtr;
- ++endPtr;
- while (*endPtr && *endPtr != '"')
- ++endPtr;
- }
- else
- {
- while (*endPtr && !white(*endPtr))
- ++endPtr;
- }
- // the special name "MFS" means all multi-file selected files
- if ( endPtr == argPtr + 3
- && *argPtr == 'M' && *(argPtr+1) == 'F' && *(argPtr+2) == 'S')
- argumentType = kMFS_Arg;
- else if (endPtr - argPtr > 4)
- {
- if ( *(endPtr-1) == 'o' && *(endPtr-2) == 'r'
- && *(endPtr-3) == 'p' && *(endPtr-4) == '.' )
- argumentType = kProfileName_Arg;
- }
- }
- // All done when hit a null byte
- else
- {
- endPtr = argPtr;
- }
- *argPtrP = argPtr;
- argLength = endPtr - argPtr;
- *argLengthP = argLength;
- return argumentType;
- }
-
- Boolean DoIndentDialog()
- {
- MenuHandle theMenu;
- DialogPtr dPtr;
- Handle theHandle;
- Rect theBox;
- Point pt;
- long aLong;
- short theID, menuItem;
- short kind, itemHit, badChar, theType;
- char mText[64];
- Boolean checkValue;
- UserItemUPP IndentPopProcUPP;
- UserItemUPP ButtonProcUPP;
-
- if (!GetAndAlignDialog(IndentDlogID))
- return(FALSE);
- dPtr = GetNewDialog(IndentDlogID, NULL, (WindowPtr)-1L);
-
- CreateIndentProgramResourcePopups();
-
- /* attach procs for popups */
- IndentPopProcUPP = NewUserItemProc(IndentPopProc);
-
- GetDItem(dPtr, ProfilePopup, &kind, &theHandle, &theBox);
- SetDItem(dPtr, ProfilePopup, kind, (Handle)IndentPopProcUPP, &theBox);
-
- GetDItem(dPtr, OutputPopup, &kind, &theHandle, &theBox);
- SetDItem(dPtr, OutputPopup, kind, (Handle)IndentPopProcUPP, &theBox);
-
- GetDItem(dPtr, InputPopup, &kind, &theHandle, &theBox);
- SetDItem(dPtr, InputPopup, kind, (Handle)IndentPopProcUPP, &theBox);
-
- /*...and buttons */
- ButtonProcUPP = NewUserItemProc(ButtonProc);
- GetDItem(dPtr, RunUserItem, &kind, &theHandle, &theBox);
- SetDItem(dPtr,RunUserItem, kind, (Handle)ButtonProcUPP, &theBox);
-
- /* init IndentSetup */
- gIndentSetup.profileName = gIndentSetup.inputName = NULL;
- gIndentSetup.outputName = NULL;
- ResetIndentSetup(dPtr); /* clears popup contents too */
-
- SetPopupMark(MainProfileID, gIndentSetup.profileMenuNum);
- SetPopupMark(InputID, gIndentSetup.inputType);
- SetPopupMark(OutputID, gIndentSetup.outputType);
-
- ShowWindow(dPtr);
- SetPort(dPtr);
-
-
- InitCursor();
- itemHit = 99;
- while (itemHit > 2) /* ie not Run/Cancel */
- {
- ModalDialog(NULL, &itemHit);
- switch (itemHit)
- {
- case ProfilePopup:
- /* Treat any pick from this menu as request
- to change main profile */
- GetDItem(dPtr, ProgramStat, &kind, &theHandle, &theBox);
- InvertRect(&theBox);
- pt.v = theBox.top;
- pt.h = theBox.right;
- LocalToGlobal(&pt);
- theMenu = GetMHandle(MainProfileID);
- aLong = PopUpMenuSelect(theMenu, pt.v, pt.h, 1);
- theID = HiWord(aLong);
- menuItem = LoWord(aLong);
- InvertRect(&theBox);
- if (menuItem > 0) /* get profile, if not canned set it up */
- {
- GetIndentProfileName(dPtr, menuItem);
- RedrawItem(dPtr, itemHit);
- }
- break;
- case InputPopup:
- GetDItem(dPtr, InputStat, &kind, &theHandle, &theBox);
- InvertRect(&theBox);
- pt.v = theBox.top;
- pt.h = theBox.right;
- LocalToGlobal(&pt);
- theMenu = GetMHandle(InputID);
- aLong = PopUpMenuSelect(theMenu, pt.v, pt.h, gIndentSetup.inputType);
- theID = HiWord(aLong);
- menuItem = LoWord(aLong);
- InvertRect(&theBox);
- if (menuItem > 0)
- gIndentSetup.inputType = menuItem;
- if (menuItem == inPop.frontSelected)
- {
- ;
- }
- else if (menuItem == inPop.frontAll)
- {
- ;
- }
- else if (menuItem == inPop.multiSelected)
- {
- ;
- }
- else if (menuItem == inPop.specificFile)
- {
- GetInputFileName();
- }
- if (menuItem > 0 && menuItem != inPop.specificFile)
- {
- if (gIndentSetup.inputName)
- {
- DisposPtr(gIndentSetup.inputName);
- gIndentSetup.inputName = NULL;
- SetItem(theMenu, inPop.specificFile, (StringPtr)"\pSelect input file...");
- }
- }
- if (menuItem > 0)
- {
- SetPopupMark(InputID, gIndentSetup.inputType);
- RedrawItem(dPtr, itemHit);
- MaintainOutputPopup();
- RedrawItem(dPtr, OutputPopup);
- }
- break;
- case OutputPopup:
- GetDItem(dPtr, OutputStat, &kind, &theHandle, &theBox);
- InvertRect(&theBox);
- pt.v = theBox.top;
- pt.h = theBox.right;
- LocalToGlobal(&pt);
- theMenu = GetMHandle(OutputID);
- aLong = PopUpMenuSelect(theMenu, pt.v, pt.h, 1);
- theID = HiWord(aLong);
- menuItem = LoWord(aLong);
- InvertRect(&theBox);
- if (menuItem > 0)
- {
- gIndentSetup.outputType = menuItem;
- SetPopupMark(OutputID, gIndentSetup.outputType);
- RedrawItem(dPtr, itemHit);
- }
- break;
- case AboutIndent:
- OKStopAlert("Copyright © 1991, Free Software Foundation.\r\
- Indent comes with ABSOLUTELY NO WARRANTY. This is free software, and \
- you are welcome to distribute it under the terms of the GNU General \
- Public License, which covers both the warranty information and the \
- terms for redistribution.\r\
- You should have received a copy of the GNU General Public License along \
- with this program (see COPYING Indent); if not, write to the Free Software Foundation, Inc., \
- 675 Mass Ave, Cambridge, MA 02139, USA.");
- break;
- }
- }
-
- // TEST ONLY DELETE
- // DisposeRoutineDescriptor(IndentPopProcUPP);
- // DisposeRoutineDescriptor(ButtonProcUPP);
-
- /* cancelled? */
- if (itemHit == 2) /* cancel */
- {
- if (gIndentSetup.profileName)
- DisposPtr(gIndentSetup.profileName);
- if (gIndentSetup.inputName)
- DisposPtr(gIndentSetup.inputName);
- if (gIndentSetup.outputName)
- DisposPtr(gIndentSetup.outputName);
- DisposDialog(dPtr);
- DestroyIndentPopups();
- return(FALSE);
- }
- /* translate to "commmand" line */
- if(!GetCommandLineFromDlogResult())
- {
- DisposDialog(dPtr);
- DestroyIndentPopups();
- return(FALSE);
- }
-
- //GetCheck (dPtr, ShowOut, &checkValue);
- //gIndentSetup.showOut = checkValue;
- DisposDialog(dPtr);
- DestroyIndentPopups();
- return(TRUE);
- }
-
- /* Called for each run.
- The input selection popup depends on what extensions have
- been passed in for this run. A largely pointless exercise in
- dynamically maintaining a menu, yet Apple disapproves of
- disabling items in a popup menu, so this approach has the
- virtue of being not-officially-frowned-upon. */
- void CreateIndentProgramResourcePopups()
- {
- MenuHandle theMenu;
-
- CreateProfilePopup();
-
- theMenu = NewMenu(InputID, (StringPtr)"\pInput");
- if (HasGetFrontText())
- {
- inPop.frontSelected = 1;
- inPop.frontAll = 2;
- AppendMenu(theMenu, (StringPtr)"\pFront text selection");
- AppendMenu(theMenu, (StringPtr)"\pAll of front text");
- }
- else
- {
- inPop.frontSelected = inPop.frontAll = 0;
- }
- if (HasGetNextMultiFile())
- {
- if (inPop.frontSelected)
- inPop.multiSelected = 3;
- else
- inPop.multiSelected = 1;
- AppendMenu(theMenu, (StringPtr)"\pMFS selected files");
- }
- else
- inPop.multiSelected = 0;
- if (inPop.frontSelected || inPop.multiSelected)
- {
- if (inPop.multiSelected == 3) /* all present */
- inPop.specificFile = 5;
- else if (inPop.multiSelected == 1) /* front options missing */
- inPop.specificFile = 3;
- else /* multi missing, therefore hasgetfront */
- inPop.specificFile = 4;
- AppendMenu(theMenu, (StringPtr)"\p-");
- }
- else
- {
- inPop.specificFile = 1;
- }
- /* This option is always available */
- AppendMenu(theMenu, (StringPtr)"\pSelect input file...");
- InsertMenu(theMenu, -1);
-
- // Output popup is dynamically created according to the current
- // input option.
- MaintainOutputPopup(); //creates it if necessary
- }
-
- /* The possibilities are:
- "\pBack up and overwrite": if MFS or one specific file
- "\pRename with number" : one specific file only
- "\pTo $tempStdOut" : if one specific file or stdin
- */
- void MaintainOutputPopup()
- {
- MenuHandle theMenu;
- short n;
- short i;
- OutputPopupItems outPopOld = outPop; // sa
- Boolean resetType = false;
-
- theMenu = GetMHandle(OutputID);
- if (theMenu == NULL)
- {
- theMenu = NewMenu(OutputID, (StringPtr)"\pOutput");
- InsertMenu(theMenu, -1);
- resetType = true;
- }
-
- // Clean out the menu, we will rebuild it here
- n = CountMItems(theMenu);
- for (i = n; i >= 1; --i)
- {
- DeleteMenuItem(theMenu, i);
- }
- // Which input item is selected?
- // stdin
- if ( inPop.frontSelected == gIndentSetup.inputType
- || inPop.frontAll == gIndentSetup.inputType )
- {
- outPop.replaceWithBackup = outPop.renameWithNumber = 0;
- outPop.toStandardOut = 1;
- AppendMenu(theMenu, (StringPtr)"\pTo $tempStdOut");
- }
- // MFS
- else if (inPop.multiSelected == gIndentSetup.inputType)
- {
- outPop.toStandardOut = outPop.renameWithNumber = 0;
- outPop.replaceWithBackup = 1;
- AppendMenu(theMenu, (StringPtr)"\pBack up and overwrite");
- }
- else if (inPop.specificFile == gIndentSetup.inputType)
- {
- outPop.replaceWithBackup = 1;
- outPop.renameWithNumber = 2;
- outPop.toStandardOut = 3;
- AppendMenu(theMenu, (StringPtr)"\pBack up and overwrite");
- AppendMenu(theMenu, (StringPtr)"\pRename with number");
- AppendMenu(theMenu, (StringPtr)"\pTo $tempStdOut");
- }
- else
- {
- ;// error
- }
-
- // Should we reset type?
- if ( outPop.replaceWithBackup != outPopOld.replaceWithBackup
- || outPop.renameWithNumber != outPopOld.renameWithNumber
- || outPop.toStandardOut != outPopOld.toStandardOut )
- gIndentSetup.outputType = 1;
-
- // Restore item mark.
- SetPopupMark(OutputID, gIndentSetup.outputType);
- }
-
- /* When Indent is called, the current working folder is the one
- containing Indent - search it for the folder "Indent profiles".
- If found, add all TEXT files whose names end with ".pro" to the
- program popup, in alpha order. */
- void CreateProfilePopup()
- {
- MenuHandle theMenu;
- char curvolName[32];
- long theDirID;
-
- theMenu = NewMenu(MainProfileID, (StringPtr)"\pProfiles");
- AppendMenu(theMenu, (StringPtr)"\pSelect unlisted profile...");
- AppendMenu(theMenu, (StringPtr)"\p-");
- AppendMenu(theMenu, (StringPtr)"\p-");
- AppendMenu(theMenu, (StringPtr)"\pGNU, the default");
- AppendMenu(theMenu, (StringPtr)"\pK & R");
- AppendMenu(theMenu, (StringPtr)"\pBerkeley");
-
-
- if (theDirID = FindIndentProfileFolder(curvolName, (char *)"\pIndent profiles"))
- AddProfilesToMenu(curvolName, theDirID, theMenu);
- InsertMenu(theMenu, -1);
- }
-
- long FindIndentProfileFolder(char *curvolName, char *folderName)
- {
- HFileInfo myCPB;
- WDPBRec theParms;
- char fName[32];
- long theDirID;
- short codeVRefNum, index = 1, len;
- OSErr err;
-
-
- GetVol(NULL, &codeVRefNum);
- /* Extract "\pVolName:" and dirID for code resource folder */
- theParms.ioNamePtr = (StringPtr)(curvolName);
- theParms.ioVRefNum = codeVRefNum;
- theParms.ioWDIndex = 0;
- theParms.ioWDProcID = 0;
- if (PBGetWDInfo(&theParms,false))
- {
- OKStopAlert("Bad working directory");
- return(0L);
- }
- len = curvolName[0];
- curvolName[len + 1] = ':';
- curvolName[0] = len + 1;
-
- theDirID = theParms.ioWDDirID;
-
- myCPB.ioNamePtr = (StringPtr)fName;
- myCPB.ioVRefNum = theParms.ioWDVRefNum;
- do
- {
- myCPB.ioFDirIndex = index;
- myCPB.ioDirID = theDirID;
- if ((err = PBGetCatInfo((CInfoPBPtr)&myCPB, FALSE)) == noErr)
- {
- if (((myCPB.ioFlAttrib>>4) & 0x01) == 1) /* a folder */
- {
- if (PEqualStrs((Byte *)fName, (Byte *)folderName))
- return(myCPB.ioDirID);
- }
- }
- ++index;
- } while (err == noErr);
- /* OKStopAlert("hawk program folder not found"); if you're testing */
- return(0L);
- }
-
- void AddProfilesToMenu(char *curvolName, long theDirID, MenuHandle theMenu)
- {
- HFileInfo myCPB;
- WDPBRec theParms;
- HVolumeParam vParms;
- char fName[32], volName[32];
- short index = 1, theVolRef, vRefNum;
- OSErr err;
- Boolean firstAdd = TRUE;
-
- /* Some shenanigans to open working directory for code resources */
- BlockMove(curvolName, volName, 32);
- vParms.ioCompletion = NULL;
- vParms.ioNamePtr = (StringPtr)(volName);
- vParms.ioVRefNum = -32768;
- vParms.ioVolIndex = -1;
- if (PBHGetVInfo((HParmBlkPtr)&vParms, FALSE))
- theVolRef = 0;
- else
- theVolRef = vParms.ioVRefNum;
- theParms.ioCompletion = NULL;
- theParms.ioVRefNum = theVolRef;
- theParms.ioNamePtr = NULL;
- theParms.ioWDDirID = theDirID;
- theParms.ioWDProcID = 'ERIK';
- if (PBOpenWD(&theParms, FALSE)) /* IM IV pg 158 */
- vRefNum = 0;
- else
- vRefNum = theParms.ioVRefNum;
-
- theParms.ioNamePtr = NULL;
- theParms.ioVRefNum = vRefNum;
- theParms.ioWDIndex = 0;
- theParms.ioWDProcID = 0;
- if (PBGetWDInfo(&theParms,false))
- return;
- gIndentSetup.defaultVRefNum = vRefNum; /* saved away, folder is left open */
-
- myCPB.ioNamePtr = (StringPtr)fName;
- myCPB.ioVRefNum = theParms.ioWDVRefNum;
- do
- {
- myCPB.ioFDirIndex = index;
- myCPB.ioDirID = theDirID;
- if ((err = PBGetCatInfo((CInfoPBPtr)&myCPB, FALSE)) == noErr)
- {
- if (((myCPB.ioFlAttrib>>4) & 0x01) != 1) /* a file */
- {
- /* fName holds name of file */
- /* Is it the right kind of file? */
- if (myCPB.ioFlFndrInfo.fdType == 'TEXT'
- && fName[0] >= 5
- && fName[fName[0]] == 'o'
- && fName[fName[0]-1] == 'r'
- && fName[fName[0]-2] == 'p'
- && fName[fName[0]-3] == '.' )
- {
- if (firstAdd)
- {
- AppendMenu(theMenu, (StringPtr)"\p-");
- firstAdd = FALSE;
- }
- AlphaAppendMenu(theMenu, 8, fName);
- }
- }
- }
- ++index;
- } while (err == noErr);
- if (firstAdd) /* none added */
- {
- theParms.ioVRefNum = vRefNum;
- PBCloseWD(&theParms, FALSE);
- }
- }
-
- void AlphaAppendMenu(MenuHandle theMenu, short lowPoint, char *name)
- {
- short newItemNum,
- highPoint = CountMItems(theMenu);
-
-
- newItemNum = AlphaMenuPos(name, theMenu, highPoint, lowPoint);
- if (newItemNum > 0)
- {
- /*error duplicate - unlikely for file list. */
- return;
- }
- else
- newItemNum = -newItemNum;
- InsMenuItem(theMenu, (StringPtr)"\pa", newItemNum - 1);
- SetItem(theMenu, newItemNum, (StringPtr)name);
- }
-
- /* Binary search existing menu for match against nameptr; if
- match return lowPoint:highPoint. If no match let n = where name would
- be inserted, range lowPoint:highPoint+1, return -n. For insertion, do
- InsMenuItem(theMenu, (StringPtr)"\pa", n - 1); -see just above.
- */
- short AlphaMenuPos(char *name, MenuHandle theMenu, short highPoint, short lowPoint)
- {
- short index;
-
- if (highPoint < lowPoint)
- return(-lowPoint);
-
- do
- {
- index = (lowPoint + highPoint)/2;
- if (MenuCompare(name, theMenu, index) < 0)
- highPoint = index - 1;
- else
- lowPoint = index + 1;
- } while (MenuCompare(name, theMenu, index) && lowPoint <= highPoint);
- if (!MenuCompare(name, theMenu, index)) /* a hit */
- return(index);
- /* lowPoint went "one too far", ie it is number that name will be after insertion */
- return(-lowPoint);
- }
-
- short MenuCompare(char *name, MenuHandle theMenu, short index)
- {
- char itemStr[64];
-
- GetItem(theMenu, index, (StringPtr)itemStr);
- /* Fudge, both mark and item strs are pascal, but warp to ptr/len vs pascal.
- Sorry folks, doing it this way because I had the tested code already. */
- return(PtrLenPascalCompare(name + 1L, name[0], itemStr));
- }
-
- /* Compare, for ptr, len vs pascal strings.
- Compare pattern with target, returning number
- reflecting alphabetical rather than ascii order.
- */
- typedef Byte *BPtr;
- short PtrLenPascalCompare(Ptr spatPtr, short patLen, Ptr stargetPtr)
- {
- BPtr patPtr = (BPtr)spatPtr,
- patEndPtr = patPtr + patLen,
- curPtr = (BPtr)stargetPtr + 1,
- curEndPtr = curPtr + (unsigned short)(stargetPtr[0]);
- short i, j;
-
- while (patPtr < patEndPtr && curPtr < curEndPtr && *patPtr == *curPtr)
- {
- ++patPtr;
- ++curPtr;
- }
-
- if (patPtr == patEndPtr && curPtr == curEndPtr) /* exact match */
- return(0);
- if (patPtr == patEndPtr && curPtr != curEndPtr) /* pattern too short */
- return(-1);
- if (patPtr != patEndPtr && curPtr == curEndPtr) /* starget too short */
- return(1);
-
- /* true miscompare within string */
- i = (short)*patPtr;
- j = (short)*curPtr;
- /* sequence: nonalpha, AaBbCc...Zz */
- /* 'A' = 65, 'a' = 97; move 'U' to 'U'*2 + 256, 'u' to 'u'*2 + 193 */
- /* 'A' -> 386, 'B' -> 388, 'a' -> 387, 'b' -> 389 etc */
- if ('A' <= i && i <= 'Z')
- i = i*2 + 256;
- else if ('a' <= i && i <= 'z')
- i = i*2 + 193;
- if ('A' <= j && j <= 'Z')
- j = j*2 + 256;
- else if ('a' <= j && j <= 'z')
- j = j*2 + 193;
- return(i - j);
- }
-
- /* Somebody's watching, so draw in the popup menus. */
- pascal void IndentPopProc(WindowPtr wdPtr, short item)
- {
- GrafPtr savePort;
- short kind, menuNum, i, n, markChar;
- Handle theHandle;
- MenuHandle theMenu;
- Rect box;
- Byte mText[64];
-
- GetPort(&savePort);
- SetPort (wdPtr);
-
- if (item == ProfilePopup)
- theMenu = GetMHandle(MainProfileID);
- else if (item == InputPopup)
- theMenu = GetMHandle(InputID);
- else if (item == OutputPopup)
- theMenu = GetMHandle(OutputID);
- else
- return;
- n = CountMItems(theMenu);
- for (i = 1; i <= n; ++i)
- {
- GetItemMark(theMenu, i, &markChar);
- if (markChar == ' ')
- break;
- }
- if (i <= n)
- menuNum = i;
- else
- menuNum = 1;
-
- GetDItem(wdPtr, item, &kind, &theHandle, &box);
- GetItem(theMenu, menuNum, mText);
- EraseRect(&box);
- TextBox(&(mText[1]),(unsigned char)(mText[0]),&box,teJustLeft);
- box.left -= 1;
- box.top -= 1;
- box.right += 1;
- box.bottom += 1;
- FrameRect(&box);
- MoveTo(box.left + 1, box.bottom);
- LineTo(box.right, box.bottom);
- MoveTo(box.right, box.top + 1);
- LineTo(box.right, box.bottom);
- SetPort(savePort);
- }
-
- pascal void ButtonProc(WindowPtr wdPtr, short item)
- {
- GrafPtr savePort;
- PenState savePen;
- Handle h;
- Rect theBox;
- short theType, ovalSize, i;
-
- GetDItem(wdPtr,item,&theType,&h,&theBox);
- GetPort(&savePort);
- SetPort(wdPtr);
- GetPenState(&savePen);
- PenNormal();
- PenSize(2,2);
-
- InsetRect(&theBox,-3,-3);
- ovalSize = (theBox.bottom + 8 - theBox.top) / 2;
- FrameRoundRect(&theBox,ovalSize,ovalSize);
-
- SetPenState(&savePen);
- SetPort(savePort);
- }
-
- void ResetIndentSetup(DialogPtr dPtr)
- {
- MenuHandle theMenu;
- short itemHit, numItems;
-
- gIndentSetup.profileMenuNum = gIndentSetup.outputType = gIndentSetup.inputType = 1;
- gIndentSetup.showOut = false;
- if (gIndentSetup.profileName)
- {
- DisposPtr(gIndentSetup.profileName);
- gIndentSetup.profileName = NULL;
- }
- if (gIndentSetup.inputName)
- {
- DisposPtr(gIndentSetup.inputName);
- gIndentSetup.inputName = NULL;
- }
- if (gIndentSetup.outputName)
- {
- DisposPtr(gIndentSetup.outputName);
- gIndentSetup.outputName = NULL;
- }
- theMenu = GetMHandle(MainProfileID);
- SetItem(theMenu, 1, (StringPtr)"\pSelect unlisted profile...");
- theMenu = GetMHandle(InputID);
- SetItem(theMenu, inPop.specificFile, (StringPtr)"\pSelect input file...");
-
- MaintainOutputPopup();
- }
-
- /* A space character is used to mark the currently-selected item,
- avoiding the horror of attempting to access global variables
- within the pascal callback above, within a CODE resource. */
- void SetPopupMark(short theMenuID, short newItem)
- {
- short i, n, markChar;
- MenuHandle theMenu;
-
- theMenu = GetMHandle(theMenuID);
- n = CountMItems(theMenu);
- for (i = 1; i <= n; ++i)
- {
- GetItemMark(theMenu, i, &markChar);
- if (markChar == ' ')
- {
- if (i == newItem)
- return;
- else
- SetItemMark(theMenu, i, 0);
- }
- else if (i == newItem)
- {
- markChar = ' ';
- SetItemMark(theMenu, i, markChar);
- }
- }
- }
-
- void GetIndentProfileName(DialogPtr dPtr, short item)
- {
- MenuHandle theMenu;
- Point where;
- SFReply reply;
- SFTypeList types;
- long len;
- short numTypes;
- Boolean userLocated;
-
- if (item == 1)
- {
- /* display dialog, get program name and input file name */
- types[0] = 'TEXT';
- types[1] = 'RRRS';
- numTypes = 2;
- GetDlogOrigin (getDlgID, &where);
- SFGetFile (where, (StringPtr)"\p", NULL, numTypes, types, NULL, &reply);
- if (!reply.good)
- return;
- userLocated = TRUE;
- }
- else /* either listed or unlisted program - the unlisted one is number 3 */
- {
- if (item == gIndentSetup.profileMenuNum) /* nothing new */
- return;
- theMenu = GetMHandle(MainProfileID);
- GetItem(theMenu, item, (StringPtr)(reply.fName));
- userLocated = FALSE;
- }
- /* reset gIndentSetup, partial */
- if (gIndentSetup.profileName)
- {
- DisposPtr(gIndentSetup.profileName);
- gIndentSetup.profileName = NULL;
- }
-
- gIndentSetup.profileName = NewPtr(256);
- if (MemError() != noErr)
- {
- gIndentSetup.profileVRefNum = 0;
- MemoryAlert();
- HiliteDlgControl(dPtr, 1, 255);
- return;
- }
- if (userLocated)
- gIndentSetup.profileVRefNum = reply.vRefNum;
- else if (item == 3)
- gIndentSetup.profileVRefNum = gIndentSetup.otherVRefNum;
- else
- gIndentSetup.profileVRefNum = gIndentSetup.defaultVRefNum;
- if (userLocated)
- gIndentSetup.profileMenuNum = 3;
- else
- gIndentSetup.profileMenuNum = item;
- AppendPStr((Byte *)(FullPathNameFromVRefNum(gIndentSetup.profileVRefNum,(Byte *)(gIndentSetup.profileName))),
- (Byte *)(reply.fName));
- SetPtrSize(gIndentSetup.profileName, gIndentSetup.profileName[0]+1);
- PtoCstr((StringPtr)gIndentSetup.profileName); /* also done by LoadIndentDlogFromHS */
- /* Restore saved invocation */
- if (userLocated || item > 6)
- InitIndentFromProfile(gIndentSetup.profileName);
- theMenu = GetMHandle(MainProfileID);
- if (userLocated)
- SetItem(theMenu, 3, reply.fName);
- /* Enable Run and SaveSettings buttons */
- HiliteDlgControl(dPtr, 1, 0);
- if (item == 1)
- item = 3;
- SetPopupMark(MainProfileID, item);
-
- /* Redraw done by caller */
- }
-
- void GetInputFileName()
- {
- MenuHandle theMenu;
- Point where;
- SFReply reply;
- SFTypeList types;
- long len;
- short numTypes;
-
- /* display dialog, get program name and input file name */
- types[0] = 'TEXT';
- types[1] = 'RRRS';
- numTypes = 2;
- GetDlogOrigin (getDlgID, &where);
- SFGetFile (where, (StringPtr)"\p", NULL, numTypes, types, NULL, &reply);
- if (!reply.good)
- return;
-
- if (gIndentSetup.inputName)
- {
- DisposPtr(gIndentSetup.inputName);
- gIndentSetup.inputName = NULL;
- }
- gIndentSetup.inputName = NewPtr(256);
- if (MemError() != noErr)
- {
- MemoryAlert();
- return;
- }
- AppendPStr((Byte *)(FullPathNameFromVRefNum(reply.vRefNum,(Byte *)(gIndentSetup.inputName))),
- (Byte *)(reply.fName));
- PtoCstr((StringPtr)gIndentSetup.inputName);
- /* Set menu */
- theMenu = GetMHandle(InputID);
- SetItem(theMenu, inPop.specificFile, reply.fName);
- }
-
- void DestroyIndentPopups()
- {
- MenuHandle theMenu;
-
- theMenu = GetMHandle(MainProfileID);
- if (!theMenu)
- return;
- DeleteMenu(MainProfileID);
- DisposeMenu(theMenu);
-
- theMenu = GetMHandle(OutputID);
- if (!theMenu)
- return;
- DeleteMenu(OutputID);
- DisposeMenu(theMenu);
-
- theMenu = GetMHandle(InputID);
- if (!theMenu)
- return;
- DeleteMenu(InputID);
- DisposeMenu(theMenu);
- }
-
- /* Command line for awk proper, generated from user
- dialog choices and variable entries.
- Indent -fProgname -fLibraries -vVariables -- inputfiles
- */
- Boolean GetCommandLineFromDlogResult()
- {
- long len;
- short i;
- Boolean passCannedProfile = false;
-
- if (gIndentSetup.inputType == inPop.specificFile && !(gIndentSetup.inputName))
- {
- /* A suspicious case, arrived at thru:
- - pick "Specific file..." option for input, and then cancel
- to, in effect, select the empty file.
- So return false */
- return false;
- }
- argc = 0;
- argv = (char **)malloc( sizeof(char *) * NUMARGVS );
- if (argv == NULL)
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- // Indent name always as first arg.
- len = strlen(gacc.thisCodeName);
- argv[argc] = NewPtr(len+1);
- if (!argv[argc])
- return(FALSE);
- BlockMove(gacc.thisCodeName, argv[argc], len+1);
- ++argc;
-
- // Do we need to pass a canned profile?
- if ( gIndentSetup.profileMenuNum == 1
- || (4 <= gIndentSetup.profileMenuNum && gIndentSetup.profileMenuNum <= 6) )
- {
- passCannedProfile = true;
- if ( gIndentSetup.profileMenuNum == 1
- || gIndentSetup.profileMenuNum == 4 )
- {
- argv[argc] = NewPtr(5);
- if (MemError() != noErr)
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- BlockMove("-gnu", argv[argc], 5);
- ++argc;
- }
- else if (gIndentSetup.profileMenuNum == 5)
- {
- argv[argc] = NewPtr(4);
- if (MemError() != noErr)
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- BlockMove("-kr", argv[argc], 4);
- ++argc;
- }
- else if (gIndentSetup.profileMenuNum == 6)
- {
- argv[argc] = NewPtr(6);
- if (MemError() != noErr)
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- BlockMove("-orig", argv[argc], 6);
- ++argc;
- }
- // else you added one and didn't tell me!
- }
-
- // The output options.
- if (gIndentSetup.outputType == outPop.toStandardOut)
- {
- argv[argc] = NewPtr(4);
- if (MemError() != noErr)
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- BlockMove("-st", argv[argc], 4);
- ++argc;
-
- gIndentSetup.showOut = true;
- }
- else if (gIndentSetup.outputType == outPop.renameWithNumber)
- {
- // Put "-o" followed by new file name
- argv[argc] = NewPtr(3);
- if (MemError() != noErr)
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- BlockMove("-o", argv[argc], 3);
- ++argc;
-
- // This option applies only to one specific file
- argv[argc] = GetRenumberedName(gIndentSetup.inputName);
- if (!argv[argc])
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- ++argc;
- }
- // else the standard rename with backup
-
- // Get input file if any.
- if ( gIndentSetup.inputType == inPop.frontSelected
- || gIndentSetup.inputType == inPop.frontAll )
- {
- argv[argc] = CreateStdIn(gIndentSetup.inputType == inPop.frontAll);
- if (!argv[argc])
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- ++argc;
- }
- else if (gIndentSetup.inputType == inPop.multiSelected)
- {
- if (!GetInputsFromMFS())
- {
- CleanUpAfterIndent();
- return(FALSE);
- }
- }
- else if (gIndentSetup.inputType == inPop.specificFile && gIndentSetup.inputName)
- {
- argv[argc] = gIndentSetup.inputName;
- ++argc;
- }
-
- return(TRUE);
- }
-
- /* If user wants the input to be whatever is in the front text file,
- get a copy of the text and write it the the file used for standard input. */
- char *CreateStdIn(Boolean wholeFile)
- {
- Ptr copyOfName;
- Handle hText;
- long len;
- OSErr IOResult;
- short refNum;
-
- // anything?
- if (HasGetFrontText())
- {
- hText = GetFrontText(wholeFile);
- }
- else
- hText = NewHandle(0);
- if (!hText)
- return(NULL);
-
- // save to standard input file
- // Delete the file. We don't care if there's an error
- FSDelete((StringPtr)gacc.stdInFileNameP, 0);
-
- // Now try to create it. '????' is the creator. Report the file error, if any
- if (IOResult = Create((StringPtr)gacc.stdInFileNameP, 0, '????', 'TEXT'))
- {
- DisposHandle(hText);
- OKStopAlert("Standard input file could not be created.");
- return(NULL);
- }
-
- if (IOResult = FSOpen ((StringPtr)gacc.stdInFileNameP, 0, &refNum))
- {
- DisposHandle(hText);
- OKStopAlert("Standard input file could not be opened.");
- return(NULL);
- }
- len = GetHandleSize(hText);
- if (IOResult = FSWrite (refNum, &len, *hText))
- {
- FSClose (refNum);
- DisposHandle(hText);
- OKStopAlert("Standard input file could not be written to.");
- return(NULL);
- }
- FSClose (refNum);
- DisposHandle(hText);
- // return ptr to copy of gacc.stdInFileName if success, or NULL
- len = strlen(gacc.stdInFileName);
- copyOfName = NewPtr(len+1);
- if (!copyOfName)
- return(NULL);
- BlockMove(gacc.stdInFileName, copyOfName, len+1);
- return(copyOfName);
- }
-
- /* Build list of files from multi-file search or equivalent selection.
- This version, concoct full path name for each file.
- Next version, use dirID and save much space. */
- Boolean GetInputsFromMFS()
- {
- char **newArgv;
- Byte *tempPtr, *endPtr;
- short whichPane, index, vRefNum, lastvrefnum = 0;
- char fileName[32];
-
- if (!HasGetNextMultiFile()) return(FALSE);
- /* determine which file to search next */
- whichPane = -1;
- GetNextMultiFile(&whichPane, &index, &vRefNum, fileName, FALSE);
- if (index < 0)
- return(FALSE);
- while (index >= 0)
- {
- tempPtr = (Byte *)malloc(256);
- if (tempPtr == NULL)
- return FALSE;
- /* This is a prime target for optimizing, since it does a lot of
- disk-pounding to retrieve the full path name. Detecting a run of
- the same vrefnum certainly helps.*/
- if (vRefNum != lastvrefnum) /* do it the hard way */
- AppendPStr((Byte *)(FullPathNameFromVRefNum(vRefNum, tempPtr)),
- (Byte *)(fileName));
- else
- {
- BlockMove(argv[argc-1], (Ptr)tempPtr, 256);
- CtoPstr((Ptr)tempPtr);
- /* strip previous file name */
- endPtr = tempPtr + tempPtr[0];
- while (*endPtr != ':')
- --endPtr;
- tempPtr[0] = (unsigned char)(endPtr - tempPtr);
- /* append new file name */
- AppendPStr(tempPtr, (Byte *)(fileName));
- }
- PtoCstr((StringPtr)tempPtr);
- argv[argc++] = (Ptr)tempPtr;
- lastvrefnum = vRefNum;
- GetNextMultiFile(&whichPane, &index, &vRefNum, fileName, FALSE);
- if (index >= 0 && argc > NUMARGVS - 1)
- { /* This is the only place where argv[] can overflow */
- NUMARGVS += 100; /* Apologies, NUMARGVS is actually a variable */
- newArgv = (char **)malloc(sizeof(char *) * NUMARGVS);
- if (newArgv == NULL)
- return FALSE;
- BlockMove((Ptr)argv, (Ptr)newArgv, sizeof(char *) * (NUMARGVS - 100));
- free(argv);
- argv = newArgv;
- }
- }
- return(TRUE);
- }
-
- /* Given "X:Y:...:File~22.c" use "X:Y:...:File~23.c"
- --or if "X:Y:...:File.c" use "X:Y:...:File~1.c"
- Keep incrementing version number until file does not exist.
- Return NULL if resulting proper name would exceed 31 chars.
- */
- char *GetRenumberedName(char *oldName)
- {
- Ptr copyOfName;
- long len;
- short refNum;
- short counter = 0;
- OSErr theErr = noErr;
- Boolean nameExists = true;
-
- if (oldName == NULL)
- return NULL;
-
- len = strlen(oldName) + 6;
- copyOfName = NewPtr(len+1);
- if (!copyOfName)
- return(NULL);
- BlockMove(oldName, copyOfName, len+1);
- CtoPstr(copyOfName);
- do
- {
- if (!IncrementName((StringPtr)copyOfName))
- {
- counter = 1000;
- break;
- }
- theErr = FSOpen((StringPtr)copyOfName, 0, &refNum);
- if (theErr == noErr)
- FSClose(refNum);
- else
- nameExists = false;
- } while (nameExists && ++counter < 1000);
-
- if (counter >= 1000)
- {
- DisposePtr(copyOfName);
- copyOfName = NULL;
- }
- else
- PtoCstr((StringPtr)copyOfName);
-
- return(copyOfName);
- }
-
- /* Locate and increment version number at end of name (set to ~1 if none present).
- Returns false if resulting name would be too long.
- */
- Boolean IncrementName(StringPtr copyOfName)
- {
- StringPtr startVNumber, endVNumber;
- StringPtr properNameStart;
- Str31 versionNumberStr;
- long versionNumber;
- short oldNumberLength;
- short newNumberLength;
- Boolean haveVersionNumber = false;
- Boolean result = true;
-
- endVNumber = ©OfName[copyOfName[0]];
- properNameStart = endVNumber;
-
- while ( properNameStart > copyOfName
- && *properNameStart != ':' )
- --properNameStart;
- ++properNameStart;
-
- while ( endVNumber > properNameStart
- && *endVNumber != '.' )
- --endVNumber;
-
- if (endVNumber > properNameStart)
- {
- startVNumber = endVNumber;
- while (startVNumber > properNameStart && num(*(startVNumber-1)) )
- --startVNumber;
- if ( startVNumber < endVNumber
- && startVNumber > properNameStart
- && *(startVNumber-1) == '~' )
- haveVersionNumber = true;
- }
- if (haveVersionNumber)
- {
- oldNumberLength = endVNumber - startVNumber;
- versionNumberStr[0] = oldNumberLength;
- BlockMove(startVNumber, versionNumberStr+1, versionNumberStr[0]);
- StringToNum(versionNumberStr, &versionNumber);
- ++versionNumber;
- NumToString(versionNumber, versionNumberStr);
- newNumberLength = versionNumberStr[0];
-
- if (newNumberLength > oldNumberLength) // new number is longer
- {
- short extra;
- short numToMove;
- // Make room for extra digits first
- extra = newNumberLength - oldNumberLength;
- numToMove = ©OfName[copyOfName[0]] + 1 - endVNumber;
- BlockMove(endVNumber, endVNumber + extra, numToMove);
-
- copyOfName[0] += extra;
- }
- // Move in the new number.
- BlockMove(versionNumberStr+1, startVNumber, newNumberLength);
- }
- else // no existing version number, make one up
- {
- short extra;
- short numToMove;
-
- versionNumberStr[0] = 2;
- versionNumberStr[1] = '~';
- versionNumberStr[2] = '1';
-
- extra = versionNumberStr[0];
- // Was there a trailing file extension?
- if (endVNumber <= properNameStart)
- {
- endVNumber = ©OfName[copyOfName[0]] + 1;
- }
- numToMove = ©OfName[copyOfName[0]] + 1 - endVNumber;
- if (numToMove > 0)
- BlockMove(endVNumber, endVNumber + extra, numToMove);
- copyOfName[0] += extra;
- // Move in the new number just created.
- BlockMove(versionNumberStr+1, endVNumber, versionNumberStr[0]);
- }
-
- // resulting name is unusable if it is too long
- if (©OfName[copyOfName[0]] + 1 - properNameStart > 31)
- result = false;
- return result;
- }
-
- void RedrawItem(DialogPtr dPtr, short itemHit)
- {
- GrafPtr savePort;
- short kind;
- Handle theHandle;
- MenuHandle theMenu;
- Rect box;
-
- GetPort(&savePort);
- SetPort (dPtr);
- GetDItem(dPtr, itemHit, &kind, &theHandle, &box);
- InvalRect(&box);
- SetPort(savePort);
- }
-
- void RedrawDialog(DialogPtr dPtr)
- {
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort (dPtr);
- InvalRect(&dPtr->portRect);
- SetPort(savePort);
- }
-
- /* Bail out if error during Indent run. */
- void JumpOnIndentError(short inputErrorNumber)
- {
-
- gInputError = inputErrorNumber;
- longjmp(envBuf, 1); /* return to save point */
- }
-
- void HandleIndentError()
- {
- /* -future- use gInputError */
- SysBeep(2);
- }
-
-